package com.caocaog.market.service.impl;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caocaog.market.common.PushCommon;
import com.caocaog.market.data.transfer.service.MkSiteBasicService;
import com.caocaog.market.dms.dto.QueryOrderDto;
import com.caocaog.market.dms.service.DmsService;
import com.caocaog.market.dms.vo.QueryOrderVo;
import com.caocaog.market.entity.*;
import com.caocaog.market.entity.dto.NightFare;
import com.caocaog.market.finance.entity.FinanceLine;
import com.caocaog.market.finance.entity.MkBillBase;
import com.caocaog.market.finance.entity.MkBillHistory;
import com.caocaog.market.finance.service.FinanceLineService;
import com.caocaog.market.finance.service.MkBillBaseService;
import com.caocaog.market.finance.service.MkBillHistoryService;
import com.caocaog.market.mapper.OrderBaseMapper;
import com.caocaog.market.merchant.entity.MkMerchantBasic;
import com.caocaog.market.merchant.service.MkMerchantService;
import com.caocaog.market.pay.syb.dto.SybDto;
import com.caocaog.market.service.*;
import com.caocaog.market.toccpt.marketmodel.OrderContrastCcpt;
import com.caocaog.market.toccpt.service.ApiForOrderService;
import com.caocaog.market.toccpt.service.OrderContrastCcptService;
import com.caocaog.market.toccpt.vo.CcptOrderInfo;
import com.caocaog.market.util.DistanceUtil;
import com.caocaog.market.utils.*;
import com.caocaog.market.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.CheckFailedException;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;

/**
 * 商品订单信息表
 *
 * @author jeecg-boot
 * @date 2021-11-29
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderBaseServiceImpl extends ServiceImpl<OrderBaseMapper, OrderBase> implements IOrderBaseService {
    @Autowired
    private IOrderLineService orderLineService;
    @Autowired
    private IOrderDeliveryService orderDeliveryService;
    @Autowired
    private IOrderPayService orderPayService;
    @Autowired
    private IOrderPromoService orderPromoService;
    @Autowired
    private ShopPromoService shopPromoService;
    @Autowired
    private ShopPromoHisService shopPromoHisService;
    @Autowired
    private IGoodsBasicService goodsBasicService;
    @Autowired
    private IShopBasicService shopBasicService;
    @Autowired
    private IMemberAddressService memberAddressService;
    @Autowired
    private ShopDeliveryService shopDeliveryService;
    @Autowired
    private ShopKilometerPriceService shopKilometerPriceService;
    @Autowired
    private IShopTakeoutService shopTakeoutService;
    @Autowired
    private MkBillHistoryService mkBillHistoryService;
    @Autowired
    private MkBillBaseService mkBillBaseService;
    private final FinanceLineService financeLineService;
    @Autowired
    private IOrderStatusInfoService orderStatusInfoService;
    @Autowired
    private IOrderRefundService orderRefundService;
    @Autowired
    private MkMerchantService merchantService;
    @Autowired
    private ShopPrinterService shopPrinterService;
    @Autowired
    private CommonAPI commonAPI;
    @Autowired
    private ApiForOrderService apiForOrderService;
    @Autowired
    private IPageViewService iPageViewService;

    private ShopCartService shopCartService;
    private GoodsSpecService goodsSpecService;

    private GoodsAttrService goodsAttrService;
    private GoodsCategoriesService goodsCategoriesService;
    private GoodsBaseService goodsBaseService;
    private GoodsHisService goodsHisService;
    private PushCommon pushCommon;
    private PushMessageTemplateService pushMessageTemplateService;

    private OrderContrastCcptService orderContrastCcptService;

    @Resource
    private ShopFareConfigService shopFareConfigService;

    @Resource
    private MealNumberUtil mealNumberUtil;

    @Resource
    private MkSiteBasicService siteBasicService;

    @Resource
    private DmsService dmsService;

    @Override
    public OrderBase selectOrderInfo(String orderId) {
        OrderBase orderBase = this.baseMapper.selectById(orderId);
        if (null == orderBase) {
            throw new JeecgBootException("订单不存在");
        }
        //order pay
        //order promo
        //order delivery
        //order line
        List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", orderId));
        OrderDelivery orderDelivery = orderDeliveryService.getOne(new QueryWrapper<OrderDelivery>().eq("order_id", orderId));
        List<OrderPromo> orderPromos = orderPromoService.list(new QueryWrapper<OrderPromo>().eq("order_id", orderId));
        List<ShopPromoHis> orderPromoList = new ArrayList<>();
        if (oConvertUtils.isNotEmpty(orderPromos)) {
            for (OrderPromo promo : orderPromos) {
                ShopPromoHis shopPromo = shopPromoHisService.getById(promo.getPromoId());
                orderPromoList.add(shopPromo);
            }
        }

        OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderId));
        ShopBasic shopBasic = shopBasicService.getById(orderBase.getShopId());
        if (null != shopBasic) {
            orderBase.setLat(shopBasic.getLat());
            orderBase.setLng(shopBasic.getLng());
            orderBase.setShopLogo(shopBasic.getLogo());
            orderBase.setShopName(shopBasic.getName());
            orderBase.setServicePhone(shopBasic.getServicePhone());
        }
        for (OrderLine orderLine : orderLineList) {
            GoodsHis goodsHis = goodsHisService.getByIdCache(orderLine.getGoodsHisId());
            if (null != goodsHis) {
                orderLine.setPicture(goodsHis.getPicture());
            }
        }
        // CcptOrderInfo ccptOrderInfo = this.getCcptOrderInfo(orderBase);
//        if (oConvertUtils.isNotEmpty(ccptOrderInfo)) {
//            orderBase.setCcptOrderInfo(ccptOrderInfo);
//        }

        QueryOrderVo vo = queryOrderVo(orderBase.getOrderNo(), orderBase.getShopId());
        if (oConvertUtils.isNotEmpty(vo)) {
            orderBase.setQueryOrderVo(vo);
        }
        String sitePhone = commonAPI.findSitePhoneBySiteId(orderBase.getSiteId());
        if (!sitePhone.contains(StringPool.AT))
            orderBase.setSitePhone(sitePhone);
        orderBase.setOrderPay(null == orderPay ? new OrderPay() : orderPay);
        orderBase.setOrderDelivery(orderDelivery);
        orderBase.setOrderLineList(orderLineList);
        orderBase.setOrderPromoList(orderPromoList);
        return orderBase;
    }

    @Override
    public OrderBase selectOrderInfoByOrderNo(String orderNo) {
        OrderBase orderBase = this.baseMapper.selectOne(new QueryWrapper<OrderBase>().eq("order_no", orderNo));
        if (oConvertUtils.isEmpty(orderBase)) {
            throw new CheckFailedException("未找到此订单，编号：" + orderNo);
        }
        String orderId = orderBase.getId();
        //order pay
        //order promo
        //order delivery
        //order line
        List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", orderId));
        log.info("打印 orderLineList ========");
        orderLineList.forEach(orderLine -> log.info(orderLine.toString()));
        OrderDelivery orderDelivery = orderDeliveryService.getOne(new QueryWrapper<OrderDelivery>().eq("order_id", orderId));
        List<OrderPromo> orderPromos = orderPromoService.list(new QueryWrapper<OrderPromo>().eq("order_id", orderId));
        List<ShopPromoHis> orderPromoList = new ArrayList<>();
        if (oConvertUtils.isNotEmpty(orderPromos)) {
            for (OrderPromo promo : orderPromos) {
                ShopPromoHis shopPromo = shopPromoHisService.getById(promo.getPromoId());
                orderPromoList.add(shopPromo);
            }
        }

        OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderId));
        orderBase.setOrderPay(orderPay);
        orderBase.setOrderDelivery(orderDelivery);
        orderBase.setOrderLineList(orderLineList);
        orderBase.setOrderPromoList(orderPromoList);
//        CcptOrderInfo ccptOrderInfo = this.getCcptOrderInfo(orderBase);
//        if (oConvertUtils.isNotEmpty(ccptOrderInfo)) {
//            orderBase.setCcptOrderInfo(ccptOrderInfo);
//        }

        QueryOrderVo vo = queryOrderVo(orderBase.getOrderNo(), orderBase.getShopId());
        if (oConvertUtils.isNotEmpty(vo)) {
            orderBase.setQueryOrderVo(vo);
        }
        return orderBase;
    }

    @Override
    public IPage<OrderBase> selectOrderListForMember(OrderBase orderBase, Integer pageNo, Integer pageSize) {
        //全部 配送单 自提单 退款
        QueryWrapper<OrderBase> queryWrapper = QueryGenerator.initQueryWrapper(orderBase, null);
        Page<OrderBase> page = new Page<OrderBase>(pageNo, pageSize);
        queryWrapper.eq("member_id", orderBase.getMemberId());
        queryWrapper.eq("is_show", 0);
        boolean search_refund = false;
        if (oConvertUtils.isNotEmpty(orderBase.getStatus())) {
            queryWrapper.eq("status", orderBase.getStatus());
            search_refund = true;
        }
        if (oConvertUtils.isNotEmpty(orderBase.getType())) {
            queryWrapper.eq("type", orderBase.getType());
        }
        queryWrapper.orderByDesc("create_time");
        IPage<OrderBase> orderBaseList = super.baseMapper.selectPage(page, queryWrapper);

        for (OrderBase base : orderBaseList.getRecords()) {
            List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", base.getId()));
            OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", base.getId()));
            OrderDelivery orderDelivery = orderDeliveryService.getOne(new QueryWrapper<OrderDelivery>().eq("order_id", base.getId()));
            ShopBasic shopBasic = shopBasicService.getById(base.getShopId());
            base.setShopLogo(null == shopBasic ? "" : shopBasic.getLogo());
            base.setOrderLineList(orderLineList.size() > 0 ? orderLineList : new ArrayList<>());
            base.setOrderPay(null == orderPay ? new OrderPay() : orderPay);
            base.setOrderDelivery(null == orderDelivery ? new OrderDelivery() : orderDelivery);
            //
            if (search_refund) {
                OrderRefund orderRefund = orderRefundService.getOne(new QueryWrapper<OrderRefund>().eq("order_id", base.getId()));
                base.setOrderRefund(null == orderRefund ? new OrderRefund() : orderRefund);
            }
            if (base.getStatus().equals("2")) {
//                CcptOrderInfo ccptOrderInfo = this.getCcptOrderInfo(base);
//                if (oConvertUtils.isNotEmpty(ccptOrderInfo)) {
//                    base.setCcptOrderInfo(ccptOrderInfo);
//                }
                QueryOrderVo vo = queryOrderVo(base.getOrderNo(), base.getShopId());
                if (oConvertUtils.isNotEmpty(vo)) {
                    base.setQueryOrderVo(vo);
                }
            }
        }

        return orderBaseList;
    }

    @Override
    public CcptOrderInfo getCcptOrderInfo(OrderBase orderBase) {
        try {
            //获取跑腿骑士详情
            Result result = apiForOrderService.findCcptOrderStatus(orderBase.getId());
            if (result.isSuccess()) {
                JSONObject jsonObject = new JSONObject(result.getResult());
                CcptOrderInfo ccptOrderInfo = jsonObject.toBean(CcptOrderInfo.class);
                String status = ccptOrderInfo.getCcptOrderStatus();
                /**
                 * 跑腿系统中的订单状态 1：支付成功待接单，2：已接单，3：骑士到店，4：已取货/配送中，5：已送达，6：订单完成，
                 *      下面的这三个状态不用管
                 *      21：用户取消订单，22：代理商取消订单，23：总后台取消订单
                 */
                Date date = new Date();
                if (status.equals("1")) {
                    //支付成功待接单
                } else if (status.equals("2")) {
                    //已接单
                    if (oConvertUtils.isNotEmpty(ccptOrderInfo.getCcptStaffReceiveTime())) {
                        String datestr = ccptOrderInfo.getCcptStaffReceiveTime();//Date的默认格式显示
                        Date date1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK).parse(datestr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        date = sdf.parse(sdf.format(date1));
                    }
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), ccptOrderInfo.getCcptStaffName()
                            , ccptOrderInfo.getCcptStaffMobile(),
                            "骑手已接单", date);
                } else if (status.equals("3")) {
                    //骑手到店
                    if (oConvertUtils.isNotEmpty(ccptOrderInfo.getCcptStaffReadyTime())) {
                        String datestr = ccptOrderInfo.getCcptStaffReadyTime();//Date的默认格式显示
                        Date date1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK).parse(datestr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        date = sdf.parse(sdf.format(date1));
                    }
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), ccptOrderInfo.getCcptStaffName()
                            , ccptOrderInfo.getCcptStaffMobile(), "骑手已到店", date);
                } else if (status.equals("4")) {
                    //已取货/配送中
                    if (oConvertUtils.isNotEmpty(ccptOrderInfo.getCcptStaffTakeTime())) {
                        String datestr = ccptOrderInfo.getCcptStaffTakeTime();//Date的默认格式显示
                        Date date1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK).parse(datestr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        date = sdf.parse(sdf.format(date1));
                    }
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), ccptOrderInfo.getCcptStaffName()
                            , ccptOrderInfo.getCcptStaffMobile(), "骑手正在配送中", date);
                } else if (status.equals("5")) {
                    //已送达,订单完成
                    if (oConvertUtils.isNotEmpty(ccptOrderInfo.getCcptStaffSendTime())) {
                        String datestr = ccptOrderInfo.getCcptStaffSendTime();//Date的默认格式显示
                        Date date1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK).parse(datestr);
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        date = sdf.parse(sdf.format(date1));
                    }
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), ccptOrderInfo.getCcptStaffName()
                            , ccptOrderInfo.getCcptStaffMobile(), "已送达", date);
                    this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "",
                            "已完成", date);
                }

                return ccptOrderInfo;
            } else {
                log.error("获取骑手信息异常：" + result.getMessage() + " " + orderBase.getOrderNo() + " " + orderBase.getStatus());
                return null;
            }
        } catch (Exception e) {
            throw new JeecgBootException("获取骑手信息异常" + orderBase.getOrderNo() + " " + orderBase.getStatus() + " " + e.getMessage());
        }

    }

    @Override
    public IPage<OrderBase> selectOrderListForMerchant(OrderBase orderBase, Integer pageNo, Integer pageSize) {
        //全部 配送单 自提单 退款
        QueryWrapper<OrderBase> queryWrapper = QueryGenerator.initQueryWrapper(orderBase, null);
        Page<OrderBase> page = new Page<OrderBase>(pageNo, pageSize);
        if (oConvertUtils.isNotEmpty(orderBase.getShopId())) {
            queryWrapper.eq("shop_id", orderBase.getShopId());
        }
        if (oConvertUtils.isNotEmpty(orderBase.getMerchantId())) {
            queryWrapper.eq("merchant_id", orderBase.getMerchantId());
        }

        queryWrapper.notIn("status", 0, -1);
        queryWrapper.eq("is_show", 0);
        boolean search_refund = false;
        if (oConvertUtils.isNotEmpty(orderBase.getStatus())) {
            queryWrapper.eq("status", orderBase.getStatus());
            search_refund = true;
        }
        if (oConvertUtils.isNotEmpty(orderBase.getType())) {
            queryWrapper.eq("type", orderBase.getType());
        }
        queryWrapper.orderByDesc("create_time");
        IPage<OrderBase> orderBaseList = super.baseMapper.selectPage(page, queryWrapper);
        List<OrderBase> list = new ArrayList<>();
        for (OrderBase base : orderBaseList.getRecords()) {
            List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", base.getId()));
            OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", base.getId()));
            OrderDelivery orderDelivery = orderDeliveryService.getOne(new QueryWrapper<OrderDelivery>().eq("order_id", base.getId()));
            ShopBasic shopBasic = shopBasicService.getById(base.getShopId());
            base.setShopLogo(null == shopBasic ? "" : shopBasic.getLogo());
            base.setOrderLineList(orderLineList.size() > 0 ? orderLineList : new ArrayList<>());
            base.setOrderPay(null == orderPay ? new OrderPay() : orderPay);
            base.setOrderDelivery(null == orderDelivery ? new OrderDelivery() : orderDelivery);
            base.setMealNumber(mealNumberUtil.getMealNumber(base.getShopId(), base.getId(), base.getCreateTime()));

            if (search_refund) {
                OrderRefund orderRefund = orderRefundService.getOne(new QueryWrapper<OrderRefund>().eq("order_id", base.getId()));
                base.setOrderRefund(null == orderRefund ? new OrderRefund() : orderRefund);
            }
            if (base.getStatus().equals("2")) {
//                CcptOrderInfo ccptOrderInfo = this.getCcptOrderInfo(base);
//                if (oConvertUtils.isNotEmpty(ccptOrderInfo)) {
//                    base.setCcptOrderInfo(ccptOrderInfo);
//                }
                QueryOrderVo vo = queryOrderVo(base.getOrderNo(), base.getShopId());
                if (oConvertUtils.isNotEmpty(vo)) {
                    base.setQueryOrderVo(vo);
                }
            }
        }

        return orderBaseList;
    }

    /**
     * 订单的下单方法
     *
     * @param vo     下单的参数信息
     * @param member 下单人的参数信息
     * @return 下单结果
     */
    @Override
    @Transactional
    public Result add(OrderForOneVo vo, Member member) {
        log.info("单商品下订单");
        //单商品订单
        //分站 商家 店铺
        //商品行
        //分站
        if (oConvertUtils.isEmpty(vo.getMerchantId())) {
            return Result.error("参数错误");
        }
        if (vo.getOrderLineList().size() < 1) {
            return Result.error("参数错误:请至少选择一个商品下单哦");
        }
        MkMerchantBasic merchant = merchantService.findMerchantById(vo.getMerchantId());
        if (null == merchant) {
            return Result.error("参数错误,暂无此商家");
        }
        OrderBase orderBase = new OrderBase();
        BeanUtils.copyProperties(vo, orderBase);
        orderBase.setSiteId(merchant.getSiteId());
        orderBase.setCreateBy(member.getLoginName());
        orderBase.setCreateTime(new Date());
        orderBase.setRemark(vo.getRemake());
        /*订单号规则 时间yyyymmddhhmmssSSS加手机号后四位加来源*/
        String phone = member.getMobile();
        Date date = new Date();
        String timestamp = DateUtils.date2Str(date, DateUtils.yyyymmddhhmmssSSS.get());
        String orderNo = timestamp + phone.substring(phone.length() - 5) + vo.getSource();
        orderBase.setOrderNo(orderNo);
        String orderId = IdWorker.getIdStr();
        orderBase.setId(orderId);
        orderBase.setStatus("0");//待付款

        List<GoodsSpec> goodsSpecList = new ArrayList<>();
        List<GoodsBase> goodsBaseList = new ArrayList<>();
        ShopBasic shopBasic = shopBasicService.getById(vo.getShopId());
        if (null == shopBasic || shopBasic.getAudit() != 1 || shopBasic.getStatus() != 0) {
            return Result.error("操作异常:店铺不存在或者已被冻结");
        }
        ShopVo shopVo = new ShopVo();
        LocalDateTime now = LocalDateTime.now();
        BeanUtils.copyProperties(shopBasic, shopVo);
        shopVo.setInBusiness(now);
        // 不在营业时间
        if (!shopVo.isInBusiness()) {
            return Result.error("很抱歉，此店铺已打烊，（" + shopBasic.getBusinessStd() + "~" + shopBasic.getBusinessEnd() + "）");
        }
        ShopTakeout shopTakeout = shopTakeoutService.getOne(new QueryWrapper<ShopTakeout>().eq("shop_id", vo.getShopId()));
        BigDecimal onlineSumPrice = new BigDecimal("0");
        BigDecimal sumPrice;
        BigDecimal packSumPrice = new BigDecimal("0");
        // 合计可得积分点数
        BigDecimal sumPoint = new BigDecimal("0");

        for (OrderLine line : vo.getOrderLineList()) {
            BigDecimal onlinePrice;
            GoodsBase goodsBase = goodsBaseService.getByIdCache(line.getGoodsId());
            if (!goodsBase.getStatus().equals("1")) {
                return Result.error("该商品已经下架了哟");
            }
            GoodsHis goodsHis = goodsHisService.getOne(new QueryWrapper<GoodsHis>().eq("goods_id", line.getGoodsId())
                    .orderByDesc("create_time")
                    .last("limit 1"));

            // 更新销量 订单完成后再加
            goodsBase.setSaleNum(goodsBase.getSaleNum() + 1);
            goodsBase.setVisitNum(goodsBase.getVisitNum() + 1);
            line.setGoodsHisId(goodsHis.getId());
            line.setOrderId(orderId);
            line.setOrderNo(orderNo);
            line.setCreateBy(member.getLoginName());
            //是否选中(有无)规格
            if (oConvertUtils.isNotEmpty(line.getSpecHisId())) {
                GoodsSpec specifications = goodsSpecService.getGoodsSpec(line.getSpecHisId());
                //check 合计金额是否正确
                BigDecimal specOnePrice = new BigDecimal(specifications.getPrice());
                onlinePrice = new BigDecimal(line.getQuantity()).multiply(specOnePrice);
                packSumPrice = packSumPrice.add(new BigDecimal(specifications.getPackFee()).multiply(new BigDecimal(line.getQuantity())));
                // 减库存
                specifications.setStock(specifications.getStock() - 1);
                goodsSpecList.add(specifications);
                // 合计可得积分
                BigDecimal thisGoodPoints = specifications.getGoodPoint() == null ? new BigDecimal(0) : specifications.getGoodPoint();
                sumPoint = sumPoint.add(thisGoodPoints);
            } else {
                List<GoodsSpec> goodsSpecifications = goodsSpecService.getGoodsSpecByGoodsId(goodsBase.getId());
                if (goodsSpecifications.isEmpty()) {
                    return Result.error("请选择规格后再下单哟~");
                }

                onlinePrice = new BigDecimal(line.getQuantity()).multiply(new BigDecimal(goodsBase.getPresentPrice()));
            }
            //check 合计金额是否正确
            if (onlinePrice.compareTo(new BigDecimal(line.getTotalPrice())) != 0) {
                return Result.error("参数错误:合计金额错误~");
            }
            onlineSumPrice = onlineSumPrice.add(onlinePrice);
            goodsBaseList.add(goodsBase);
        }


        OrderPay orderPay = new OrderPay();
        orderPay.setCreateBy(member.getLoginName());
        orderPay.setOrderId(orderId);
        orderPay.setTimePrice(BigDecimal.ZERO);
        orderPay.setWeatherPrice(BigDecimal.ZERO);
        ShopFareConfig shopFareConfig = shopFareConfigService.findShopFareConfigByShopId(shopBasic.getId());
        if (Objects.nonNull(shopFareConfig)) {
            if (shopFareConfig.getIsOpenNightlyFare() == 1) {
                orderPay.setTimePrice(NightFare.parsePriceConfig(shopFareConfig.getNightlyFares()));
            }
            if (shopFareConfig.getIsOpenSpecialWeatherFare() == 1) {
                orderPay.setWeatherPrice(shopFareConfig.getSpecialWeatherFare());
            }
        }

        orderPay.setAmount(onlineSumPrice.toString());
        // 打包费
        if (packSumPrice.compareTo(new BigDecimal("0")) == 0) {
            packSumPrice = new BigDecimal(StringUtils.isBlank(shopTakeout.getPack()) ? "0" : shopTakeout.getPack());
        }
        orderPay.setPackAmount(packSumPrice.toString());
        orderPay.setPayStatus(0);//待支付
        // 配送
        OrderDelivery orderDelivery = new OrderDelivery();
        BeanUtils.copyProperties(vo.getOrderDelivery(), orderDelivery);
        orderDelivery.setCreateBy(member.getLoginName());

        if (vo.getType() == 1) {
            orderDelivery.setDeliveryType("1");//电动车
            //外卖订单
            // 配送费
            DistanceVo distanceVo = DistanceVo.builder()
                    .addressId(vo.getAddressId())
                    .shopId(shopBasic.getId())
                    .gpsFromLat(Double.parseDouble(shopBasic.getLat()))
                    .gpsFromLng(Double.parseDouble(shopBasic.getLng()))
                    .gpsToLat(Double.parseDouble(orderDelivery.getLat()))
                    .gpsToLng(Double.parseDouble(orderDelivery.getLng()))
                    .amount(onlineSumPrice.add(packSumPrice).toString())
                    .build();
            distanceVo = this.getDeliveryAmount(distanceVo);
            orderPay.setDeliveryAmount(distanceVo.getDistanceAmount());
            orderDelivery.setDistance(distanceVo.getDistance());
        } else if (vo.getType() == 2 || vo.getType() == 3) {
            //自提单 配送为零
            orderPay.setDeliveryAmount("0");
            orderDelivery.setDistance("0");
            //生成核销码
            String code = this.getVerifyCode(shopBasic.getId());
            orderBase.setVerifyCode(code);
        } else {
            return Result.error("参数错误:值不存在~");
        }

        orderDelivery.setOrderId(orderId);
        // 参与优惠活动
        List<OrderPromo> orderPromoList = new ArrayList<>();
        if (!vo.getShopPromoHisList().isEmpty()) {
            for (ShopPromoHis his : vo.getShopPromoHisList()) {
                OrderPromo orderPromo = new OrderPromo();
                ShopPromoHis shopPromoHis = shopPromoHisService.getById(his.getId());
                if (null != shopPromoHis) {
                    orderPromo.setOrderId(orderId);
                    orderPromo.setCreateBy(member.getLoginName());
                    orderPromo.setPromoId(his.getId());
                    orderPromoList.add(orderPromo);
                } else {
                    return Result.error("参数错误:未找到该优惠活动~");
                }

            }
            orderPay.setDiscountAmount(vo.getPromoMoney());
        } else {
            //未参与优惠活动
            orderPay.setDiscountAmount("0");
        }
        //实际支付的金额 online商品价格 + 配送费+打包费+时间段加价+特殊天气加价-优惠金额
        sumPrice = onlineSumPrice
                .add(new BigDecimal(orderPay.getDeliveryAmount()))
                .add(new BigDecimal(orderPay.getPackAmount()))
                .add(orderPay.getTimePrice())
                .add(orderPay.getWeatherPrice())
                .subtract(new BigDecimal(orderPay.getDiscountAmount()));
        if (sumPrice.compareTo(new BigDecimal("0")) <= 0) {
            //实付金额优惠后金额为零时,最小支付0.01
            sumPrice = new BigDecimal("0.01");
        }
        log.info("实付金额sunPrice:" + sumPrice + " 支付金额:" + vo.getPayMoney());
        if (sumPrice.compareTo(new BigDecimal(vo.getPayMoney())) != 0) {
            return Result.error("操作失败:实付金额错误~");
        }
        orderPay.setPayAmount(sumPrice.toString());

        log.info("批量更新商品规格");
        this.goodsSpecService.updateBatchGoodsSpec(goodsSpecList);
        /*if (!goodsSpecificationsList.isEmpty()) {
            goodsSpecificationsList.forEach(goodsSpecService::updateGoodsSpec);
        }*/
        if (!goodsBaseList.isEmpty()) {
            goodsBaseService.updateBatchCache(goodsBaseList);
        }
        orderPay.setPayWay(1);//当前默认支付方式为微信小程序
        // 在插入订单数据之前，先计算出来可得积分然后
        orderBase.setTakePoint(sumPoint);
        // 然后插入订单
        super.baseMapper.insert(orderBase);
        orderLineService.saveBatch(vo.getOrderLineList());
        orderPayService.save(orderPay);
        orderDeliveryService.addOrderDelivery(orderDelivery);
        if (!orderPromoList.isEmpty()) {
            orderPromoService.saveBatch(orderPromoList);
        }

        //返回订单号 订单金额
//        orderPay.setPayAmount("0.01");
        orderBase.setOrderPay(orderPay);
        //添加状态记录
        this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "已下单", new Date());
        //清空购物车
        this.shopCartService.cleanShopCart(vo.getMemberId(), vo.getShopId());
        return Result.OK(orderBase);
    }

    /**
     * 订单下单前的计价的方法
     *
     * @param vo 计价必传参数
     * @return 计价结果
     */
    @Override
    public Result getSumPrice(OrderForOneVo vo) {
        //单商品订单
        //分站 商家 店铺
        //商品行
        //分站
        if (oConvertUtils.isEmpty(vo.getMerchantId())) {
            return Result.error("参数错误");
        }
        if (vo.getOrderLineList().isEmpty()) {
            return Result.error("参数错误:请至少选择一个商品下单哦");
        }
        MkMerchantBasic merchant = merchantService.findMerchantById(vo.getMerchantId());
        if (null == merchant) {
            return Result.error("参数错误,暂无此商家");
        }

        ShopBasic shopBasic = shopBasicService.getById(vo.getShopId());
        if (null == shopBasic || shopBasic.getAudit() != 1 || shopBasic.getStatus() != 0) {
            return Result.error("操作异常:店铺不存在或者已被冻结");
        }
        ShopVo shopVo = new ShopVo();
        LocalDateTime now = LocalDateTime.now();
        BeanUtils.copyProperties(shopBasic, shopVo);
        shopVo.setInBusiness(now);
        // 不在营业时间
        if (!shopVo.isInBusiness()) {
            return Result.error("很抱歉，此店铺已打烊，（" + shopBasic.getBusinessStd() + "~" + shopBasic.getBusinessEnd() + "）");
        }
        ShopTakeout shopTakeout = shopTakeoutService.getOne(new QueryWrapper<ShopTakeout>().eq("shop_id", vo.getShopId()));
        BigDecimal onlineSumPrice = new BigDecimal("0").setScale(2);
        BigDecimal sumPrice;
        BigDecimal packSumPrice = new BigDecimal("0").setScale(2);
        BigDecimal distanceAmount = new BigDecimal("0").setScale(2);
        BigDecimal distance = new BigDecimal("0").setScale(2);
        BigDecimal promoMoney = new BigDecimal("0").setScale(2);
        BigDecimal timePrice = BigDecimal.ZERO; // 时间段加价
        BigDecimal weatherPrice = BigDecimal.ZERO; // 特殊天气加价
        for (OrderLine line : vo.getOrderLineList()) {
            BigDecimal onlinePrice;
            GoodsBasic goodsBasic = goodsBasicService.getById(line.getGoodsId());
            if ("1".equals(goodsBasic.getStatus()) && goodsBasic.getDelFlag() == 0) {
                //是否选中(有无)规格
                if (oConvertUtils.isNotEmpty(line.getSpecHisId())) {
                    GoodsSpec specifications = goodsSpecService.getGoodsSpec(line.getSpecHisId());
                    if (specifications == null)
                        throw new CheckFailedException("部分商品规格已下架，请重写选择");
                    if (StringUtils.isBlank(specifications.getPackFee()))
                        specifications.setPackFee("0");
                    //check 合计金额是否正确
                    BigDecimal specOnePrice = new BigDecimal(specifications.getPrice());
                    onlinePrice = new BigDecimal(line.getQuantity())
                            .multiply(specOnePrice);
                    packSumPrice = packSumPrice.add(new BigDecimal(specifications.getPackFee()).multiply(new BigDecimal(line.getQuantity())));
                } else {
                    onlinePrice = new BigDecimal(line.getQuantity()).multiply(new BigDecimal(goodsBasic.getPresentPrice()));
                }
                //check 合计金额是否正确
                if (onlinePrice.compareTo(new BigDecimal(line.getTotalPrice())) != 0) {
                    return Result.error("参数错误:合计金额错误~");
                }
                onlineSumPrice = onlineSumPrice.add(onlinePrice);
            } else {
                //商品已下架
                return Result.error("该商品已经下架了哟");
            }

        }

        ShopFareConfig shopFareConfig = shopFareConfigService.findShopFareConfigByShopId(shopBasic.getId());
        if (Objects.nonNull(shopFareConfig)) {
            if (shopFareConfig.getIsOpenNightlyFare() == 1) {
                timePrice = NightFare.parsePriceConfig(shopFareConfig.getNightlyFares());
            }
            if (shopFareConfig.getIsOpenSpecialWeatherFare() == 1) {
                weatherPrice = shopFareConfig.getSpecialWeatherFare();
            }
        }


        // 打包费
        if (packSumPrice.compareTo(new BigDecimal("0")) == 0) {
            packSumPrice = new BigDecimal(StringUtils.isBlank(shopTakeout.getPack()) ? "0" : shopTakeout.getPack());
        }
//        if (vo.getType() == 1) {
//            //外卖订单
//            // 配送费
//            DistanceVo distanceVo = DistanceVo.builder()
//                    .addressId(vo.getAddressId())
//                    .shopId(shopBasic.getId())
//                    .gpsFromLat(Double.parseDouble(shopBasic.getLat()))
//                    .gpsFromLng(Double.parseDouble(shopBasic.getLng()))
//                    .gpsToLat(Double.parseDouble(vo.getOrderDelivery().getLat()))
//                    .gpsToLng(Double.parseDouble(vo.getOrderDelivery().getLng()))
//                    .amount(onlineSumPrice.add(packSumPrice).toString())
//                    .build();
//            distanceVo = this.getDeliveryAmount(distanceVo);
//            distanceAmount = new BigDecimal(distanceVo.getDistanceAmount());
//            distance = new BigDecimal(distanceVo.getDistance());
//        } else if (vo.getType() == 2 || vo.getType() == 3) {
//            //自提单 配送为零
//
//        } else {
//            return Result.error("参数错误:值不存在~");
//        }

        // 参与优惠活动
        if (!oConvertUtils.isEmpty(vo.getPromoMoney())) {
            //未参与优惠活动
            promoMoney = new BigDecimal(vo.getPromoMoney()).setScale(2);
        }
        //实际支付的金额 online商品价格 + 配送费+打包费-优惠金额
        sumPrice = onlineSumPrice
                .add(distanceAmount)
                .add(packSumPrice)
                .add(timePrice)
                .add(weatherPrice)
                .subtract(promoMoney).setScale(2);
        if (sumPrice.compareTo(new BigDecimal("0")) <= 0) {
            //实付金额优惠后金额为零时,最小支付0.01
            sumPrice = new BigDecimal("0.01");
        }

        log.info("实付金额sunPrice:" + sumPrice + ",distanceAmount:" + distanceAmount + ",distance:" + distance + ",packSumPrice:" + packSumPrice);

        Map<String, BigDecimal> map = new HashMap<>();
        map.put("sumPrice", sumPrice);
        map.put("distanceAmount", distanceAmount);
        map.put("distance", distance);
        map.put("packSumPrice", packSumPrice);
        map.put("promoMoney", promoMoney);
        map.put("timePrice", timePrice);
        map.put("weatherPrice", weatherPrice);
        return Result.OK(map);
    }

    @Override
    public void addOrderStatusInfo(String orderId, String orderNo, String createBy, String remark, String statusName, Date date) {
        OrderStatusInfo check = null;
        if (!theCustomerAppliesForARefundAgain.equals(statusName)) {
            check = orderStatusInfoService.getOne(new QueryWrapper<OrderStatusInfo>().eq("order_id", orderId)
                    .eq("order_status_name", statusName).last(" limit 1 "));
        }
        if (oConvertUtils.isEmpty(check)) {
            //添加状态记录
            OrderStatusInfo orderStatusInfo = OrderStatusInfo.builder().orderId(orderId)
                    .orderNo(orderNo).orderStatusName(statusName).createBy(createBy)
                    .createTime(new Date()).remark(remark).build();
            orderStatusInfoService.save(orderStatusInfo);
            log.info("添加订单状态记录成功：" + orderNo + statusName);
            if ("已完成".equals(statusName)) {
                //更新订单状态
                OrderBase orderBase = super.baseMapper.selectById(orderId);
                if (oConvertUtils.isNotEmpty(orderBase) && !orderBase.getStatus().equals("3")) {
                    orderBase.setStatus("3");
                    super.baseMapper.updateById(orderBase);
                }
            }
        } else {
            log.error("添加订单状态记录失败，该订单状态已存在 ：" + orderNo + statusName);
        }

    }

    public static void main(String[] args) {

        // 发货地址位置（店铺位置）
        String shopLatitude = "32.706641000000005";
        String shopLongitude = "108.97861199999996";
        // 收获地址位置
        String receiptLatitude = "32.6994514465332";
        String receiptLongitude = "109.02983093261719";


        Double distance1 = DistanceUtil.getStreetDistance(
                Double.parseDouble(shopLatitude), Double.parseDouble(shopLongitude),
                Double.parseDouble(receiptLatitude), Double.parseDouble(receiptLongitude));
        Console.log("旧版逻辑 -> " + distance1);

        Double distance2 = DistanceUtil.getStreetDistance(
                32.706641000000005, 108.97861199999996,
                32.6994514465332, 109.02983093261719);
        Console.log("正确逻辑 -> " + distance2);


        Double distance3 = DistanceUtil.getStreetDistance(
                new BigDecimal(shopLatitude).doubleValue(), new BigDecimal(shopLongitude).doubleValue(),
                new BigDecimal(receiptLatitude).doubleValue(), new BigDecimal(receiptLongitude).doubleValue());
        Console.log("新版逻辑 -> " + distance3);
    }

    @Override
    public DistanceVo getDeliveryAmount(DistanceVo vo) {
        if (oConvertUtils.isEmpty(vo.getGpsFromLat()) || oConvertUtils.isEmpty(vo.getGpsFromLng())) {
            MemberAddress memberAddress;
            //无用户的经纬度 则默认返回用户的常用地址信息
            if (oConvertUtils.isNotEmpty(vo.getAddressId())) {
                memberAddress = memberAddressService.getById(vo.getAddressId());
            } else if (oConvertUtils.isNotEmpty(vo.getMemberId())) {
                memberAddress = memberAddressService.getMemberCommonAddress(vo.getMemberId());//返回用户的常用地址top1
            } else {
                throw new JeecgBootException("参数错误");
            }
            if (null == memberAddress) {
                throw new JeecgBootException("请先添加收货地址");
            }
            vo.setGpsFromLat(Double.parseDouble(memberAddress.getLat()));
            vo.setGpsFromLng(Double.parseDouble(memberAddress.getLng()));
            vo.setAddressId(memberAddress.getId());
        }
//        double distance = DistanceUtil.getStreetDistance(vo.getGpsFromLat(), vo.getGpsFromLng(), vo.getGpsToLat(), vo.getGpsToLng());
//        vo.setDistance(Double.toString(distance));
//        log.info("配送距离distance:" + distance);
        vo.setDistance("0.00");
        vo.setDistanceAmount("0.00");
//        //获取外卖配送设置
//        ShopTakeout shopTakeout = shopTakeoutService.getOne(new QueryWrapper<ShopTakeout>().eq("shop_id", vo.getShopId()));
//        if (null == shopTakeout) {
//            log.warn("该店铺id:" + vo.getShopId() + "暂未配置外卖信息");
//        } else if (oConvertUtils.isNotEmpty(shopTakeout.getMxDistance()) && distance > Double.parseDouble(shopTakeout.getMxDistance())) {
//            throw new JeecgBootException("距离太远啦,暂时不支持配送哦,请换其他店铺试试呢");
//        } else if (oConvertUtils.isNotEmpty(shopTakeout.getStartFare()) && new BigDecimal(vo.getAmount()).compareTo(new BigDecimal(shopTakeout.getStartFare())) < 0) {
//            throw new JeecgBootException("暂未满足起送条件哦");
//        }
//        BigDecimal disPrice = new BigDecimal("0").setScale(2, BigDecimal.ROUND_UP);
//        //获取符合的配送距离
//        if (StringUtils.isNotEmpty(shopTakeout.getFreeDistribution())
//                && new BigDecimal(shopTakeout.getFreeDistribution()).compareTo(new BigDecimal("0")) != 0
//                && new BigDecimal(vo.getAmount()).compareTo(new BigDecimal(shopTakeout.getFreeDistribution())) >= 0) {
//            //免费配送 条件 满金额
//            log.info("免费配送条件-满" + shopTakeout.getFreeDistribution() + "金额免配送");
//            vo.setDistanceAmount("0");
//        } else if (StringUtils.isNotEmpty(shopTakeout.getFreeDistance())
//                && Integer.parseInt(shopTakeout.getFreeDistance()) != 0
//                && Integer.parseInt(shopTakeout.getFreeDistance()) >= distance) {
//            //符合配送的距离
//            log.info("符合配送的距离" + shopTakeout.getFreeDistance());
//            vo.setDistanceAmount("0");
//        } else {
//            //不符合免费配送条件
//            ShopDelivery shopDelivery = shopDeliveryService.getOne(new QueryWrapper<ShopDelivery>().eq("shop_id", vo.getShopId()));
//            if (null != shopDelivery) {
//                //起送公里 起送价
////                if (shopDelivery.getStartKilometer().doubleValue() < distance) {
//                disPrice = disPrice.add(shopDelivery.getStartPrice());
//                distance = new BigDecimal(Double.toString(distance)).setScale(0, RoundingMode.UP).doubleValue();
////                }
//                //超出价格 超出公里
//                if (distance > shopDelivery.getExceedKilometer().doubleValue()) {
//                    BigDecimal exceedPrice = new BigDecimal(Double.toString(distance))
//                            .subtract(shopDelivery.getExceedKilometer())
//                            .multiply(shopDelivery.getExceedPrice());
//                    disPrice = disPrice.add(exceedPrice);
//                }
//                //配送范围 计算
//                if (StringUtils.isNotEmpty(shopDelivery.getIntervalRange())) {
//                    String[] kilIds = shopDelivery.getIntervalRange().split(",");
//                    List<ShopKilometerPrice> shopKilometerPriceList = shopKilometerPriceService.list(
//                            new QueryWrapper<ShopKilometerPrice>().in("id", kilIds)
//                                    .orderByAsc("kilometer_str"));
//                    Boolean flag = false;
//                    BigDecimal defferAmount = new BigDecimal("0");
//                    for (ShopKilometerPrice kilometerPrice : shopKilometerPriceList) {
//                        BigDecimal differ = new BigDecimal("0");
//                        if (distance >= kilometerPrice.getKilometerEnd().doubleValue()) {
//                            differ = kilometerPrice.getKilometerEnd().subtract(kilometerPrice.getKilometerStr());//超过此区间内相差
//                        } else if (distance < kilometerPrice.getKilometerEnd().doubleValue() && distance > kilometerPrice.getKilometerStr().doubleValue()) {
//                            differ = new BigDecimal(Double.toString(distance)).subtract(kilometerPrice.getKilometerStr());//未超过此区间内相差
//                            flag = true;
//                        } else {
//                            break;
//                        }
//                        defferAmount = defferAmount.add(differ.multiply(kilometerPrice.getPrice()));
//                        if (flag) {
//                            break;
//                        }
//                    }
//                    disPrice = disPrice.add(defferAmount);
//                }
//
//                vo.setDistanceAmount(disPrice.setScale(1, BigDecimal.ROUND_UP).toString());
//            } else {
////            if (distance<Double.parseDouble(shopTakeout.getFreeDistance())){
//                //符合在免费配送距离内
//                vo.setDistanceAmount(disPrice.toString());
//            }
//        }


        return vo;
    }

    @Override
    public Result goodThingsAround(String siteId, int type, String lat, String lng) {
        if (type == 1) {
            //周边店铺
            List<ShopVo> shopBasicList = shopBasicService.selectShopListAndTakeOutInfoByRecommend(siteId, new ShopBasic().setRecommend(1));
            double latDouble = Double.parseDouble(lat);
            double lngDouble = Double.parseDouble(lng);
            for (ShopVo shopVo : shopBasicList) {
                //店铺的优惠
                List<ShopPromo> shopPromoList = shopPromoService.selectShopPromoByShopId(shopVo.getId());
                if (oConvertUtils.isNotEmpty(shopPromoList)) {
                    shopVo.setShopPromoList(shopPromoList);
                }
                if (oConvertUtils.isNotEmpty(shopVo.getLat()) && oConvertUtils.isNotEmpty(shopVo.getLng())) {
                    double distance = DistanceUtil.getDistanceMeter(latDouble, lngDouble,
                            Double.parseDouble(shopVo.getLat()), Double.parseDouble(shopVo.getLng()));
                    shopVo.setDistance(Double.parseDouble(String.format("%.2f", distance)));
                }

            }

            // 如果没有siteId 则超出 30km 就不显示了
            List<ShopVo> resultList = new ArrayList<>();
            if (StringUtils.isBlank(siteId)) {
                shopBasicList.forEach(shopBasic -> {
                    if (shopBasic.getDistance() >= 30) return;
                    resultList.add(shopBasic);
                });
                return Result.OK(resultList);
            } else {
                return Result.OK(shopBasicList);
            }
        } else if (type == 2) {
            //周边好物
            List<String> shopIds = shopBasicService.selectShopListAndTakeOutInfoByRecommend(siteId, new ShopBasic().setRecommend(1))
                    .stream().map(ShopVo::getShopId).collect(Collectors.toList());
            List<GoodsAroundVo> goodsVoList = new ArrayList<>();
            if (oConvertUtils.listIsNotEmpty(shopIds)) {
                List<String> descStr = new ArrayList<>();
                descStr.add("is_hot");
                descStr.add("sale_num");
                List<GoodsBasic> goodsBasicList = goodsBasicService.list(new QueryWrapper<GoodsBasic>().in("shop_id", shopIds)
                        .eq("is_index", 1)
                        .eq("status", 1)
                        .eq("del_flag", 0)
                        .orderByDesc(descStr));

                for (GoodsBasic basic : goodsBasicList) {
                    GoodsAroundVo goodsVo = new GoodsAroundVo();
                    BeanUtils.copyProperties(basic, goodsVo);
                    ShopBasic shopBasic = shopBasicService.getById(goodsVo.getShopId());
                    if (null == shopBasic || shopBasic.getAudit() != 1 || shopBasic.getStatus() != 0) {
                        continue;
                    }
                    goodsVo.setShopName(null == shopBasic ? "" : shopBasic.getName());
                    goodsVoList.add(goodsVo);
                }
            }

            return Result.OK(goodsVoList);

        } else {
            return Result.error("参数错误~");
        }

    }

    @Override
    public Result goodThingsAroundForSDX(String lat, String lng, Integer pageNo, Integer pageSize) {
        //周边好物
        //周边店铺
        List<ShopVo> shopBasicList = shopBasicService
                .selectShopListAndTakeOutInfoByRecommend(new ShopBasic().setRecommend(1));
        List<ShopVo> shopBasicListNew = new ArrayList<>();
        for (int i = 0; i < shopBasicList.size(); i++) {
            ShopVo shopVo = shopBasicList.get(i);
            if (oConvertUtils.isNotEmpty(shopVo.getLat()) && oConvertUtils.isNotEmpty(shopVo.getLng())) {
                double distance = DistanceUtil.getDistanceMeter(Double.parseDouble(lat), Double.parseDouble(lng),
                        Double.parseDouble(shopVo.getLat()), Double.parseDouble(shopVo.getLng()));
                if (distance > Double.parseDouble("35.00")) {//周边好物 暂时获取35公里内的
//                    shopBasicList.remove(i);
                    continue;
                }
                shopVo.setDistance(Double.parseDouble(String.format("%.2f", distance)));
                shopBasicListNew.add(shopVo);
            }

        }
        shopBasicListNew.sort(comparing(ShopVo::getDistance));
        List<String> shopIds = shopBasicListNew.stream().map(ShopVo::getId).collect(Collectors.toList());

        Page<GoodsBasic> goodsBasicPage = new Page<>();
        if (oConvertUtils.listIsNotEmpty(shopIds)) {
            List<String> descStr = new ArrayList<>();
            descStr.add("is_hot");
            descStr.add("sale_num");
            Page<GoodsBasic> page = new Page<GoodsBasic>(pageNo, pageSize);
            goodsBasicPage = goodsBasicService.page(page, new QueryWrapper<GoodsBasic>().in("shop_id", shopIds)
                    .eq("is_index", 1)
                    .eq("status", 1)
                    .eq("del_flag", 0)
                    .orderByDesc(descStr));

            for (GoodsBasic basic : goodsBasicPage.getRecords()) {
                GoodsAroundVo goodsVo = new GoodsAroundVo();
                BeanUtils.copyProperties(basic, goodsVo);
                ShopBasic shopBasic = shopBasicService.getById(goodsVo.getShopId());
                if (null == shopBasic || shopBasic.getAudit() != 1 || shopBasic.getStatus() != 0) {
                    continue;
                }
                goodsVo.setShopName(null == shopBasic ? "" : shopBasic.getName());
//                goodsVoList.add(goodsVo);
            }
        }
        return Result.OK(goodsBasicPage);
    }

    @Override
    public void localHandler(String payNo) {
        //支付成功后 业务逻辑处理

        OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("pay_serno", payNo));
        OrderBase orderBase = super.baseMapper.selectById(orderPay.getOrderId());
        if (null == orderBase) {
            log.error("localHandler:订单交易号不存在~");
        }
        log.info("-----支付成功后 业务逻辑处理:" + orderBase.getStatus());

        if (orderBase.getStatus().equals("1")) {
            // 生成餐号到缓存中
            mealNumberUtil.getMealNumber(orderBase.getShopId(), orderBase.getId());
            //添加状态记录
            this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "支付成功", new Date());

            // TODO delete
            // 入账 bill_base
            MkBillBase mkBillBase = mkBillBaseService.findBillIsExist(orderBase.getOrderNo());
            if (null == mkBillBase) {
                MkBillHistory billHistory = new MkBillHistory();
                billHistory.setOrderNo(orderBase.getOrderNo());
                billHistory.setPayAmount(orderPay.getPayAmount());
                billHistory.setPaySerno(orderPay.getPaySerno());
                billHistory.setPayWay(orderPay.getPayWay());
                billHistory.setPayTime(orderPay.getPayTime());
                billHistory.setCreateBy(orderBase.getCreateBy());
                int count = mkBillHistoryService.insertBillAndHistory(billHistory);
                log.info("-----微信回调:插入的条数count：" + count);
                if (count == 0) {
                    // 返回 0 表示同时插入mk_bill_base和mk_bill_history两张表失败
                    log.error("-----微信回调error:同时插入mk_bill_base和mk_bill_history两张表失败:" + orderBase.getOrderNo() + "-" + orderBase.getStatus());
                }
            } else {
                log.error("------微信回调mkBillBase:已存在,不再重复添加 " + orderBase.getOrderNo() + " - " + mkBillBase.getId());
            }

            if (null == financeLineService.getFinanceLineByOrderId(orderBase.getId())) {
                // 获取总部抽成比例
                BigDecimal systemPCT = new BigDecimal(Optional.ofNullable(Optional.ofNullable(siteBasicService.getById(orderBase.getSiteId()))
                        .orElseThrow(() -> new RuntimeException("分站不存在"))
                        .getSysRakeRate()).orElse("1")).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);

                // 获取分站抽成比例
                BigDecimal sitePCT = new BigDecimal(Optional.ofNullable(Optional.ofNullable(shopBasicService.getById(orderBase.getShopId()))
                        .orElseThrow(() -> new RuntimeException("店铺不存在"))
                        .getCommissionRate()).orElse("0"));

                Integer count = financeLineService.createFinanceLine(new FinanceLine()
                        .setOrderId(orderBase.getId())
                        .setOrderNo(orderBase.getOrderNo())
                        .setPayAmount(new BigDecimal(orderPay.getPayAmount()))
                        .setPayTime(orderPay.getPayTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime())
                        .setSystemPCT(systemPCT)
                        .setSitePCT(sitePCT)
                        .calculateShopPCT()
                );
                log.info("添加提现行记录：" + count);
            }

            log.info("-----微信回调(localHandler)成功~");
            // 打印
            this.print(orderBase.getOrderNo());
            // uni推送
            ShopBasic shopBasic = shopBasicService.getById(orderBase.getShopId());
            PushMessageTemplate pushMessageTemplate = this.pushMessageTemplateService.getPushMessageTemplateById(1);
            pushMessageTemplate.setContent(String.format(pushMessageTemplate.getContent(), shopBasic.getName()));
            pushMessageTemplate.putPayload("type", pushMessageTemplate.getId());

            this.pushCommon.toSingleByAlias(pushMessageTemplate, shopBasic.getMerchantId());

        } else {
            log.error("-----微信回调(localHandler)失败:" + orderBase.getOrderNo() + " " + orderBase.getStatus());
        }

    }

    @Override
    public Result cancelOrder(OrderBase orderBase, Member member) {
        // 回滚库存 更新状态
        List<OrderLine> orderLineList = orderLineService.list(new QueryWrapper<OrderLine>().eq("order_id", orderBase.getId()));
        orderBase.setStatus("-1");//取消
        log.info("------cancelOrder取消订单:" + orderBase.getStatus());
        for (OrderLine line : orderLineList) {
            GoodsHis goodsHis = goodsHisService.getByIdCache(line.getGoodsHisId());
            GoodsBase goodsBase = goodsBaseService.getByIdCache(goodsHis.getGoodsId());
            if (!line.getSpecHisId().isEmpty()) {
                GoodsSpec goodsSpec = goodsSpecService.getGoodsSpec(line.getSpecHisId());
                goodsSpec.setStock(goodsSpec.getStock() + line.getQuantity());//回滚库存
                goodsSpecService.updateGoodsSpec(goodsSpec);
            }
            goodsBase.setSaleNum(goodsBase.getSaleNum() - line.getQuantity());//回滚销量
            goodsBaseService.updateById(goodsBase);
        }
        super.baseMapper.updateById(orderBase);

        //添加状态记录
        this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "订单已取消", new Date());
        return Result.OK();
    }

    @Override
    public Result verifyOrder(OrderBase orderBase) {
        // 核销订单
        orderBase.setStatus("3");//已完成
        super.baseMapper.updateById(orderBase);
        //添加状态记录-已核销
        this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "订单已核销", new Date());

        //添加状态记录-已完成
        this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), "", "", "订单已完成", new Date());

        return Result.OK("核销成功");
    }

    private final static String theCustomerAppliesForARefundAgain = "客户再次申请退款";

    @Override
    public Result refundOrder(OrderRefund orderRefund, Member member, OrderBase orderBase) {
        /* 订单申请退款 */

        //取消跑腿订单
        if (Integer.parseInt(orderBase.getStatus()) > 1) { // 已发货
            Result result = apiForOrderService.cancelOrderToCcpt(orderBase.getId());
            log.info("取消跑腿订单：" + result.isSuccess() + " " + result.getMessage());
            /*if (!result.isSuccess()) {
                log.error(result.getMessage());
            } else {
                this.refundOrderPush(orderBase);
            }*/
        }

        OrderRefund check = orderRefundService.getOne(new QueryWrapper<OrderRefund>()
                .eq("order_id", orderBase.getId())
        );
        if (oConvertUtils.isEmpty(check)) {
            OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderBase.getId()));
            orderRefund.setAudit(0);//待审核
            orderRefund.setPayStatus(0);//待退款
            orderRefund.setOrderStatus(orderBase.getStatus());
            orderRefund.setCreateBy(member.getUserName());
            orderRefund.setCreateTime(DateUtils.getDate());
            orderRefund.setRefundAmount(orderPay.getPayAmount());
            orderRefund.setOrderId(orderBase.getId());
            orderRefund.setMerchantId(orderBase.getMerchantId());
            orderRefund.setShopId(orderBase.getShopId());
            /*订单号规则 时间yyyymmddhhmmssSSS加手机号后四位加来源*/
            String phone = member.getMobile();
            Date date = new Date();
            String timestamp = DateUtils.date2Str(date, DateUtils.yyyymmddhhmmssSSS.get());
            String refundNo = "T" + timestamp + phone.substring(phone.length() - 5) + orderBase.getSource();
            orderRefund.setRefundNo(refundNo);
            orderBase.setStatus("-2");//申请售后
            super.baseMapper.updateById(orderBase);
            orderRefundService.save(orderRefund);
            //添加状态记录
            this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), member.getLoginName(), "", "客户申请退款", new Date());
        } else {
            check.setAudit(0);//待审核
            check.setPayStatus(0);//待退款
            check.setOrderStatus(orderBase.getStatus());
            check.setUpdateBy(member.getUserName());
            check.setUpdateTime(DateUtils.getDate());
            orderRefundService.updateById(check);

            orderBase.setStatus("-2");//申请售后
            super.baseMapper.updateById(orderBase);
            //添加状态记录
            this.addOrderStatusInfo(orderBase.getId(), orderBase.getOrderNo(), member.getLoginName(), "", theCustomerAppliesForARefundAgain, new Date());
        }
        // 推送消息模版
        this.refundOrderPush(orderBase);
        // 打印消息
        this.print(orderBase.getOrderNo());
        // TODO delete
        //更新结算状态  3-待退款
        MkBillBase mkBillBase = mkBillBaseService.findBillIsExist(orderBase.getOrderNo());
        if (oConvertUtils.isNotEmpty(mkBillBase)) {
            mkBillBaseService.updatePayStatusAndInsertHistory(orderBase.getOrderNo(), 3);
        }
        return Result.OK("操作成功");
    }

    private void refundOrderPush(OrderBase orderBase) {
        // uniPush推送
        ShopBasic shopBasic = shopBasicService.getById(orderBase.getShopId());
        PushMessageTemplate pushMessageTemplate = this.pushMessageTemplateService.getPushMessageTemplateById(2);
        pushMessageTemplate.setContent(String.format(pushMessageTemplate.getContent(), shopBasic.getName()));
        pushMessageTemplate.putPayload("type", pushMessageTemplate.getId());

        this.pushCommon.toSingleByAlias(pushMessageTemplate, shopBasic.getMerchantId());
    }

    @Override
    public Result getShopInfo(ShopInfoVo shopInfoVo) {
        ShopBasic shopBasic = shopBasicService.getById(shopInfoVo.getId());
        if (null == shopBasic || shopBasic.getAudit() != 1 || shopBasic.getStatus() != 0) {
            return Result.error("操作异常:店铺不存在或者已被冻结");
        }

        ShopInfoVo vo = new ShopInfoVo();
        String shopId = shopBasic.getId();

        if (oConvertUtils.isEmpty(shopInfoVo.getSortId())) {

            ShopTakeout shopTakeout = shopTakeoutService.getOne(new QueryWrapper<ShopTakeout>()
                    .eq("shop_Id", shopId));
            ShopDelivery shopDelivery = shopDeliveryService.getOne(new QueryWrapper<ShopDelivery>()
                    .eq("shop_id", shopId));
            List<ShopPromo> shopPromoList = shopPromoService.selectShopPromoByShopId(shopId);
//            List<GoodsSort> goodsSortList = goodsSortService.getShopSortList(shopId); TODO 04-24号没问题后删除
            List<GoodsCategories> goodsSortList = this.goodsCategoriesService.getShowGoodsCategoriesByShopId(shopId);

            // TODO 这个应该没用过，待确定，没用就删掉
            List<GoodsVo> goodsVoPushList = goodsBasicService.getShopOfGoodsPushList(shopId, 2);

//            this.getGoodsInfo(goodsVoPushList);
            BeanUtils.copyProperties(shopBasic, vo);
            vo.setGoodsVoPushList(goodsVoPushList);
            vo.setShopDelivery(shopDelivery);
            vo.setShopTakeout(shopTakeout);
            vo.setShopPromoList(shopPromoList);
            vo.setGoodsSortList(goodsSortList);
            vo.setInBusiness(LocalDateTime.now());
//            vo.setGoodsVoList(goodsVoList);
            vo.setSortId(!goodsSortList.isEmpty() ? goodsSortList.get(0).getId() : "");
        }
        return Result.OK(vo);
    }

    @Override
    public Page getShopOfGoodsList(GoodsBasic goodsBasic, Integer pageNo, Integer pageSize) {
        System.out.println(goodsBasic);
        Page<GoodsBasic> page = new Page<GoodsBasic>(pageNo, pageSize);
        page.addOrder(new OrderItem("sort", false));
        page.addOrder(new OrderItem(CommonConstant.DEFAULT_ORDER_COLUMN, false));
        QueryWrapper<GoodsBasic> queryWrapper = QueryGenerator.initQueryWrapper(goodsBasic, null);
        queryWrapper.eq("status", 1);
        Page<GoodsBasic> goodsBasicPage = goodsBasicService.page(page, queryWrapper);

        for (GoodsBasic basic : goodsBasicPage.getRecords()) {
            List<GoodsAttr> attributeList = goodsAttrService.getGoodsAttrByGoodsId(basic.getId());
            List<GoodsSpec> specificationsList = goodsSpecService.getGoodsSpecByGoodsId(basic.getId());

            basic.setGoodsAttributeList(attributeList);
            basic.setGoodsSpecificationsList(specificationsList);

        }
        return goodsBasicPage;
    }

    /*private List<GoodsVo> getGoodsInfo(List<GoodsVo> goodsVos) {
        for (GoodsVo vo : goodsVos) {
            vo = goodsBasicService.getGoodsInfo(vo);
        }
        return goodsVos;
    }*/

    @Override
    public Result updOrderIsShow(String orderId) {
        OrderBase orderBase = super.baseMapper.selectById(orderId);
        if (orderBase.getIsShow().equals("0")) {
            orderBase.setIsShow(1);//不展示
            super.baseMapper.updateById(orderBase);
            return Result.OK(orderBase);
        } else {
            return Result.error("请勿重复操作~");
        }

    }


    @Override
    public ShopVo DayRecommend(String siteId) {
        ShopVo shopVo = new ShopVo();
        // 获取商户ids
        List<String> merchantIds = commonAPI.findMerchantForSite(siteId);
        if (merchantIds.isEmpty()) return shopVo;


        List<ShopBasic> shopBasics = shopBasicService.getBaseMapper().selectList(new QueryWrapper<ShopBasic>()
                .in("merchant_id", merchantIds)
                .eq("recommend", 1)//推荐店铺
                .eq("del_flag", 0)//未删除
                .eq("status", 0)//正常
                .eq("is_rest", 0)//营业
                .eq("audit", 1)//已审核通过
                .orderByDesc("update_time"));


        if (!shopBasics.isEmpty()) {
            LocalDateTime now = LocalDateTime.now();
            for (ShopBasic shopBasic : shopBasics) {
                BeanUtils.copyProperties(shopBasic, shopVo);
                shopVo.setInBusiness(now);
                // 不在营业时间就跳过
                if (!shopVo.isInBusiness()) continue;

                List<GoodsInfoVo> voList = shopBasicService.selectGoodsVoByShopId(shopVo.getId());
                if (oConvertUtils.listIsNotEmpty(voList)) {
                    if (voList.size() < 4) {
                        continue;
                    }
                    shopVo.setGoodsVoList(voList);
                } else {
                    continue;
                }
                List<String> str = shopPromoService.getShopPromoByShopId(shopVo.getId());
                shopVo.setShopPromoStrList(str);
                return shopVo;
            }

        }
        return shopVo;
    }

    @Override
    public List<ShopPromoHis> computeConformPromo(OrderForOneVo orderForOneVo) {
        // 校验
        if (StringUtils.isBlank(orderForOneVo.getShopId()))
            throw new CheckFailedException("店铺id（shopId）不能为空");
        if (StringUtils.isBlank(orderForOneVo.getMemberId()))
            throw new CheckFailedException("会员id（memberId）不能为空");
        if (orderForOneVo.getOrderLineList() == null || orderForOneVo.getOrderLineList().size() == 0)
            throw new CheckFailedException("请传入商品（orderLineList）");
        // 查询店铺下所有的最新促销信息（含历史表id）
        List<ShopPromoHis> shopPromoHiss = this.shopPromoHisService.selectShopPromoHisByShopId(orderForOneVo.getShopId());
        if (shopPromoHiss.isEmpty()) return new ArrayList<>();

        // 根据店铺 id 获得店铺外卖信息 并进行校验
        ShopTakeout shopTakeout = this.shopTakeoutService.getOne(
                new LambdaQueryWrapper<ShopTakeout>().eq(ShopTakeout::getShopId, orderForOneVo.getShopId()));
        if (shopTakeout == null)
            throw new JeecgBootException("未找到相应店铺外卖信息, shopId-> " + orderForOneVo.getShopId());

        // 把参数转换为 map<specId, quantity>
        Map<String, Integer> specHisIdQuantityMap = orderForOneVo.getOrderLineList().stream()
                .collect(Collectors.groupingBy(OrderLine::getSpecHisId, Collectors.summingInt(OrderLine::getQuantity)));

        for (Map.Entry<String, Integer> entry : specHisIdQuantityMap.entrySet()) {
            log.info(entry.getKey() + " = " + entry.getValue());
        }
        final BigDecimal[] totalPackageFee = {BigDecimal.ZERO};
        // 根据map中所有的规格id查询规格信息
        Map<String, BigDecimal> specPrices = this.goodsSpecService.list(
                        new LambdaQueryWrapper<GoodsSpec>().in(GoodsSpec::getId, specHisIdQuantityMap.keySet()))
                .stream().collect(Collectors.toMap(GoodsSpec::getId, goodsSpecifications -> {
                    Integer quantity = specHisIdQuantityMap.get(goodsSpecifications.getId()); // 获取数量
                    totalPackageFee[0] = totalPackageFee[0].add(new BigDecimal(goodsSpecifications.getPackFee()).multiply(new BigDecimal(quantity)));
                    if (quantity == 1) // 如果数量为 1，直接返回规格售价
                        return new BigDecimal(goodsSpecifications.getPrice());
                    else // 规格售价 * 数量
                        return new BigDecimal(goodsSpecifications.getPrice()).multiply(new BigDecimal(quantity));
                }));

        if (specHisIdQuantityMap.size() != specPrices.size())
            throw new JeecgBootException("请传入正确的规格id, 传入的规格id-> " + specHisIdQuantityMap.keySet() + "; 数据库中查出的规格id.size-> " + specPrices.size());

        // 打包费
        if (totalPackageFee[0].compareTo(new BigDecimal("0")) == 0) {
            totalPackageFee[0] = new BigDecimal(StringUtils.isBlank(shopTakeout.getPack()) ? "0" : shopTakeout.getPack());
        }
        // 计算出总花费                               // 规格售价 * 数量（使用reduce聚合函数,实现累加器）
        BigDecimal totalCost = totalPackageFee[0].add(specPrices.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add));

        Random random = new Random();
        // 客户身份筛选
        Predicate<ShopPromoHis> filterCustomerPredicate = shopPromoHis -> {
            switch (shopPromoHis.getCustomer()) {
                case "allCustomer": // 全部客户
                    return true;
                case "newCustomer": // 新客户
                    return this.isNewCustomer(orderForOneVo.getShopId(), orderForOneVo.getMemberId());
                case "oldCustomer": // 老客户
                    return !this.isNewCustomer(orderForOneVo.getShopId(), orderForOneVo.getMemberId());
                default:
                    return false;
            }
        };
        // 优惠模式进行筛选
        Predicate<ShopPromoHis> filterModelPredicate = shopPromoHis -> {
            switch (shopPromoHis.getModel()) {
                case "enough": // 满减
                    // 总花费大于等于目标金额
                    return totalCost.compareTo(shopPromoHis.getTarget()) > -1;
                case "immed": // 立减
                    return true;
                case "random": // 随机
                    if (totalCost.compareTo(shopPromoHis.getTarget()) > -1) {
                        shopPromoHis.setDiscount(new BigDecimal(random.nextInt(shopPromoHis.getDiscount().intValue()) + 1));
                        return true;
                    }
                    return false;
                default:
                    return false;
            }
        };

        Map<Integer, List<ShopPromoHis>> promoBySoleMap = shopPromoHiss.stream()
                .filter(filterCustomerPredicate)
                .filter(filterModelPredicate)
                .collect(Collectors.groupingBy(ShopPromoHis::getIsSole, Collectors.toList()));

        if (promoBySoleMap.containsKey(0)) {
            promoBySoleMap.get(0).stream()
                    .max(comparing(ShopPromoHis::getDiscount))
                    .ifPresent(shopPromoHis -> promoBySoleMap.put(0, Collections.singletonList(shopPromoHis)));
        }

        return promoBySoleMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
    }


    @Override
    public List<OrderStatusInfo> getOrderStatusInfo(String orderId) {
        return orderStatusInfoService.list(new QueryWrapper<OrderStatusInfo>().eq("order_id", orderId));
    }

    /**
     * 是否为新顾客
     *
     * @param shopId   店铺id
     * @param memberId 会员id
     * @return true/false
     */
    private boolean isNewCustomer(String shopId, String memberId) {
        return super.baseMapper.selectCount(new LambdaQueryWrapper<OrderBase>()
                .in(OrderBase::getStatus, 0, 1, 2, 3) // 只查有订单的
                .eq(OrderBase::getShopId, shopId)
                .eq(OrderBase::getMemberId, memberId)) == 0;
    }


    /**
     * 根据订单号打印
     *
     * @param orderNo 订单号
     */
    public void print(String orderNo) {
        log.info("根据订单号打印 in ->" + orderNo);
        OrderBase orderBase = this.selectOrderInfoByOrderNo(orderNo);
        ShopBasic shopBasic = this.shopBasicService.getById(orderBase.getShopId());
        // 获取店铺今天订单数
        int todayShopOrderNumber = mealNumberUtil.getMealNumber(orderBase.getShopId(), orderBase.getId(), orderBase.getCreateTime());
        // 根据门店id获取打印机列表
        this.shopPrinterService.getShopPrinterByShopId(orderBase.getShopId()).forEach(shopPrinter -> {
            switch (shopPrinter.getType()) {
                case 1: // 飞鹅
                    FePrinterUtil.print(PrintUtil.getFePrintString(todayShopOrderNumber + 1, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic), shopPrinter.getNumber(), shopPrinter.getCascadeCount());
                    break;
                case 2: // 易联云
                    YlyPrinterUtil.print(PrintUtil.getYlyPrintString(todayShopOrderNumber + 1, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic), shopPrinter.getNumber(), shopPrinter.getCascadeCount());
                    break;
                case 3: // 芯烨云
                    XyyPrinterUtil.print(PrintUtil.getXyyPrintString(todayShopOrderNumber + 1, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic), shopPrinter.getNumber(), shopPrinter.getCascadeCount());
                    break;
                case 4: // 中午
                    ZwPrinterUtil.print(PrintUtil.getZwPrintString(todayShopOrderNumber + 1, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic, shopPrinter.getCascadeCount()), shopPrinter.getNumber(), shopPrinter.getPrinterKey());
                    break;
            }
        });
    }

    @Override
    public void testPrint(String orderNo) {
        if (StringUtils.isBlank(orderNo)) {
            orderNo = "20220317155925556374621";
        }
        OrderBase orderBase = this.selectOrderInfoByOrderNo(orderNo);
        ShopBasic shopBasic = this.shopBasicService.getById(orderBase.getShopId());
        log.info("飞鹅");
        log.info(PrintUtil.getFePrintString(0, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic));
        log.info("易联云");
        log.info(PrintUtil.getYlyPrintString(0, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic));
        log.info("芯烨云");
        log.info(PrintUtil.getXyyPrintString(0, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic));
        log.info("中午");
        log.info(PrintUtil.getZwPrintString(0, orderBase, orderBase.getOrderLineList(), orderBase.getOrderPay(), orderBase.getOrderDelivery(), shopBasic, 1));
        this.print(orderNo);
    }


    @Override
    public List<OrderLine> getOrderLineByCcptOrderSid(Integer ccptOrderSid) {
        OrderContrastCcpt orderContrastCcpt = orderContrastCcptService.findByCcptOrderSid(ccptOrderSid);
        if (Objects.isNull(orderContrastCcpt) || StringUtils.isBlank(orderContrastCcpt.getMarketOrderId())) {
            return Collections.emptyList();
        }
        return orderLineService.getByOrderId(orderContrastCcpt.getMarketOrderId());
    }


    @Override
    public Integer getMealNumberByCcptOrderSid(Integer ccptOrderSid) {
        OrderContrastCcpt orderContrastCcpt = orderContrastCcptService.findByCcptOrderSid(ccptOrderSid);
        if (Objects.isNull(orderContrastCcpt) || StringUtils.isBlank(orderContrastCcpt.getMarketOrderId())) {
            return 0;
        }
        OrderBase orderBase = baseMapper.selectById(orderContrastCcpt.getMarketOrderId());
        return mealNumberUtil.getMealNumber(orderBase.getShopId(), orderBase.getId(), orderBase.getCreateTime());
        /*Random random = new Random();
        return mealNumberUtil.getMealNumber("1", String.valueOf(random.nextInt(10)));*/
    }


    @Override
    @Cacheable(value = CacheConstant.ORDER_COUNT_PAGE, key = "#id")
    public Map orderCount(String id, LoginUser loginUser) {
        Map map = new HashMap();
        QueryWrapper<OrderBase> queryWrapperOrderBase = QueryGenerator.initQueryWrapper(new OrderBase(), null);
        QueryWrapper<OrderPay> queryWrapperOrderPay = QueryGenerator.initQueryWrapper(new OrderPay(), null);
        QueryWrapper<OrderPay> queryWrapperOrderPayRank = QueryGenerator.initQueryWrapper(new OrderPay(), null);
        queryWrapperOrderBase.notIn("status", -1);
        queryWrapperOrderPay.in("pay_status", 1);
        queryWrapperOrderPayRank.notIn("pay_status", 0);
        List<String> shopIds = new ArrayList<>();
        List<String> orderIds = new ArrayList<>();
        List<RankChatVO> barData = new ArrayList<>();
        List<RankShopList> rankList = new ArrayList<>();
        List<Map<String, Object>> visitInfoMiniApp = new ArrayList<>();
        Map<String, Object> loginfoMiniApp = new HashMap<>();
        //总销售额
        BigDecimal totalAmount = new BigDecimal("0.00").setScale(2, BigDecimal.ROUND_UP);
        //昨日销售额
        BigDecimal yesterdayAmount = new BigDecimal("0.00").setScale(2, BigDecimal.ROUND_UP);
        //订单量
        int orderCount = 0;
        //昨日订单量
        int yesterdayCount = 0;
        //支付笔数
        int payCount = 0;

        if (1 == loginUser.getUserType()) {

        } else if (2 == loginUser.getUserType()) {
            //分站
            String siteId = loginUser.getSiteId();
            queryWrapperOrderBase.eq("site_id", siteId);
            //获取商户ids
            List<String> merchantIds = commonAPI.findMerchantForSite(siteId);
            //获取门店
            if (oConvertUtils.listIsNotEmpty(merchantIds)) {
                shopIds = shopBasicService.list(new QueryWrapper<ShopBasic>()
                        .in("merchant_id", merchantIds)).stream().map(ShopBasic::getId).collect(Collectors.toList());
                if (oConvertUtils.listIsEmpty(shopIds)) {
                    map.put("totalAmount", totalAmount);
                    map.put("yesterdayAmount", yesterdayAmount);
                    map.put("orderCount", orderCount);
                    map.put("yesterdayCount", yesterdayCount);
                    map.put("payCount", payCount);
                    map.put("barData", barData);
                    map.put("rankList", rankList);
                    map.put("visitInfoMiniApp", visitInfoMiniApp);
                    map.put("loginfoMiniApp", loginfoMiniApp);
                    return map;
                }
            } else {
                map.put("totalAmount", totalAmount);
                map.put("yesterdayAmount", yesterdayAmount);
                map.put("orderCount", orderCount);
                map.put("yesterdayCount", yesterdayCount);
                map.put("payCount", payCount);
                map.put("barData", barData);
                map.put("rankList", rankList);
                map.put("visitInfoMiniApp", visitInfoMiniApp);
                map.put("loginfoMiniApp", loginfoMiniApp);
                return map;
            }
        } else if (3 == loginUser.getUserType()) {
            //商户
            //商户
            String merchantId = loginUser.getMerchantId();
            queryWrapperOrderBase.eq("merchant_id", merchantId);

            shopIds = shopBasicService.list(new QueryWrapper<ShopBasic>()
                    .eq("merchant_id", merchantId)).stream().map(ShopBasic::getId).collect(Collectors.toList());
            if (oConvertUtils.listIsEmpty(shopIds)) {
                map.put("totalAmount", totalAmount);
                map.put("yesterdayAmount", yesterdayAmount);
                map.put("orderCount", orderCount);
                map.put("yesterdayCount", yesterdayCount);
                map.put("payCount", payCount);
                map.put("barData", barData);
                map.put("rankList", rankList);
                map.put("visitInfoMiniApp", visitInfoMiniApp);
                map.put("loginfoMiniApp", loginfoMiniApp);
                return map;
            }
        }
        //支付笔数
        if (1 != loginUser.getUserType()) {
            orderIds = this.baseMapper.selectList(queryWrapperOrderBase).stream().map(OrderBase::getId).collect(Collectors.toList());
            if (oConvertUtils.listIsEmpty(orderIds)) {
                map.put("totalAmount", totalAmount);
                map.put("yesterdayAmount", yesterdayAmount);
                map.put("orderCount", orderCount);
                map.put("yesterdayCount", yesterdayCount);
                map.put("payCount", payCount);
                map.put("barData", barData);
                map.put("rankList", rankList);
                map.put("visitInfoMiniApp", visitInfoMiniApp);
                map.put("loginfoMiniApp", loginfoMiniApp);
                return map;
            }
            queryWrapperOrderPay.in("order_id", orderIds);
            queryWrapperOrderPayRank.in("order_id", orderIds);
        }

        payCount = orderPayService.count(queryWrapperOrderPay);
        //总销售额
        queryWrapperOrderPay.select(" sum(pay_amount) as sumAll ");
        OrderPay orderPay = orderPayService.getOne(queryWrapperOrderPay);
        totalAmount = null == orderPay ? new BigDecimal("0") : new BigDecimal(orderPay.getSumAll()).setScale(0, BigDecimal.ROUND_UP);

        //订单量
        orderCount = this.baseMapper.selectCount(queryWrapperOrderBase);

        SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
        String start = formater.format(new Date()) + " 00:00:00";
        String end = formater.format(new Date()) + " 23:59:59";
        Date startDate = DateUtils.str2Date(start, DateUtils.datetimeFormat.get());
        Date endDate = DateUtils.str2Date(end, DateUtils.datetimeFormat.get());
        //昨日销售额
        queryWrapperOrderPay.ge("create_time", DateUtils.dateAddDays(startDate, -1));
        queryWrapperOrderPay.le("create_time", DateUtils.dateAddDays(endDate, -1));
        OrderPay orderPayYesDay = orderPayService.getOne(queryWrapperOrderPay);
        yesterdayAmount = null == orderPayYesDay ? new BigDecimal("0") : new BigDecimal(orderPayYesDay.getSumAll()).setScale(0, BigDecimal.ROUND_UP);
        //昨日订单量
        queryWrapperOrderBase.ge("create_time", DateUtils.dateAddDays(startDate, -1));
        queryWrapperOrderBase.le("create_time", DateUtils.dateAddDays(endDate, -1));
        yesterdayCount = this.baseMapper.selectCount(queryWrapperOrderBase);
        //近15天内销售额排行榜
        queryWrapperOrderPayRank.select(" sum(pay_amount) as sumAll ",
                "DATE_FORMAT(create_time,\"%Y-%m-%d\") as createTime",
                "DATE_FORMAT(create_time,\"%m-%d\") as createTimeFormat");
        queryWrapperOrderPayRank.ge("create_time", DateUtils.dateAddDays(endDate, -15));
        queryWrapperOrderPayRank.le("create_time", endDate);
        queryWrapperOrderPayRank.groupBy("DATE_FORMAT(create_time,\"%Y-%m-%d\")");
        queryWrapperOrderPayRank.groupBy("DATE_FORMAT(create_time,\"%m-%d\") ");
        queryWrapperOrderPayRank.orderByAsc("DATE_FORMAT(create_time,\"%Y-%m-%d\")");
        List<OrderPay> orderPayList = orderPayService.list(queryWrapperOrderPayRank);

        for (OrderPay pay : orderPayList) {
            RankChatVO vo = new RankChatVO();
            vo.setX(pay.getCreateTimeFormat());
            vo.setY(new BigDecimal(pay.getSumAll()).setScale(0, BigDecimal.ROUND_UP).toString());
            barData.add(vo);
        }
        //门店销售排行榜
        rankList = this.baseMapper.getRankShopList(shopIds);
        //设备统计

        // 设备访问量
        int totalVisitCount = iPageViewService.count();
        loginfoMiniApp.put("totalVisitCount", totalVisitCount);
        int todayVisitCountIOS = iPageViewService.count(new QueryWrapper<PageView>()
                .select(" distinct ip ")
                .eq("is_android", 1)
                .ge("create_time", startDate)
                .le("create_time", endDate));
        loginfoMiniApp.put("todayVisitCountIOS", todayVisitCountIOS);
        int todayVisitCountAndroid = iPageViewService.count(new QueryWrapper<PageView>()
                .select(" distinct ip ")
                .eq("is_android", 0)
                .ge("create_time", startDate)
                .le("create_time", endDate));
        loginfoMiniApp.put("todayVisitCountAndroid", todayVisitCountAndroid);
        int todayIp = iPageViewService.count(new QueryWrapper<PageView>()
                .select(" distinct ip ")
                .ge("create_time", startDate)
                .le("create_time", endDate));
        //update-end--Author:zhangweijian  Date:20190428 for：传入开始时间，结束时间参数
        loginfoMiniApp.put("todayIp", todayIp);
        //iOS android 最近7天访问量
        visitInfoMiniApp = iPageViewService.findVisitCountMiniApp();
        map.put("totalAmount", totalAmount);
        map.put("yesterdayAmount", yesterdayAmount);
        map.put("orderCount", orderCount);
        map.put("yesterdayCount", yesterdayCount);
        map.put("payCount", payCount);
        map.put("barData", barData);
        map.put("rankList", rankList);
        map.put("visitInfoMiniApp", visitInfoMiniApp);
        map.put("loginfoMiniApp", loginfoMiniApp);
        return map;
    }

    public String getVerifyCode(String shopId) {
        boolean flag = true;
        String code = "";
        while (flag) {
            code = RandomUtil.randomNumbers(6);
            OrderBase orderBase = super.baseMapper.selectOne(new QueryWrapper<OrderBase>()
                    .eq("shop_id", shopId)
                    .eq("verify_code", code)
                    .last(" limit 1 "));
            if (null == orderBase) {
                flag = false;
            }
        }
        return code;
    }

    @Override
    public QueryOrderVo queryOrderVo(String orderNo, String shopId) {
        if (Objects.isNull(orderNo)) {
            return null;
        }
        QueryOrderDto queryOrderDto = new QueryOrderDto();
        queryOrderDto.setOrderNo(orderNo);
        queryOrderDto.setShopId(shopId);
        Result<QueryOrderVo> queryOrderVoResult = dmsService.orderQuery(queryOrderDto);
        if (Objects.isNull(queryOrderVoResult)) {
            return null;
        }
        return queryOrderVoResult.getResult();
    }


    @Autowired
    public void setShopCartService(ShopCartService shopCartService) {
        this.shopCartService = shopCartService;
    }

    @Autowired
    public void setGoodsSpecService(GoodsSpecService goodsSpecService) {
        this.goodsSpecService = goodsSpecService;
    }

    @Autowired
    public void setGoodsAttrService(GoodsAttrService goodsAttrService) {
        this.goodsAttrService = goodsAttrService;
    }

    @Autowired
    public void setGoodsCategoriesService(GoodsCategoriesService goodsCategoriesService) {
        this.goodsCategoriesService = goodsCategoriesService;
    }

    @Autowired
    public void setGoodsBasicService(GoodsBaseService goodsBaseService) {
        this.goodsBaseService = goodsBaseService;
    }

    @Autowired
    public void setGoodsHisService(GoodsHisService goodsHisService) {
        this.goodsHisService = goodsHisService;
    }

    @Autowired
    public void setPushCommon(PushCommon pushCommon) {
        this.pushCommon = pushCommon;
    }

    @Autowired
    public void setPushMessageTemplateService(PushMessageTemplateService pushMessageTemplateService) {
        this.pushMessageTemplateService = pushMessageTemplateService;
    }

    @Autowired
    public void setOrderContrastCcptService(OrderContrastCcptService orderContrastCcptService) {
        this.orderContrastCcptService = orderContrastCcptService;
    }

    /**
     * 订单发货操作
     *
     * @param orderShippedVO 发货信息
     * @return 发货结果
     */
    @Override
    public Result<?> orderShipped(OrderShippedVO orderShippedVO) {
        String orderId = orderShippedVO.getOrderId();
        OrderBase orderBase = Optional.ofNullable(getById(orderId)).orElseThrow(() -> new JeecgBootException(String.format("该订单 %s 不存在！", orderId)));
        orderBase.setExpressNo(orderShippedVO.getExpressNo());
        orderBase.setStatus(CommonConstant.ORDER_STATUS_SHIPPED);
        return Result.OK("已发货");
    }

    /**
     * 订单后台完成
     *
     * @return 完成订单
     */
    @Override
    public Result<?> orderCompletion(String orderId) {
        OrderBase orderBase = Optional.ofNullable(getById(orderId)).orElseThrow(() -> new JeecgBootException(String.format("该订单 %s 不存在！", orderId)));
        orderBase.setStatus(CommonConstant.ORDER_STATUS_COMPLETED);
        return Result.OK("已完成");
    }

    /**
     * 构建这个订单的微信支付信息
     *
     * @param orderBase 订单基础信息
     * @param sybDto    支付DTO
     */
    @Override
    public void buildThisOrderMerchantPay(OrderBase orderBase, SybDto sybDto) {
        MkMerchantBasic merchantBasic = Optional.ofNullable(merchantService.getById(orderBase.getMerchantId())).orElseThrow(()->new JeecgBootException("没有这个商户信息！"));
        sybDto.setCusid(merchantBasic.getCusid());
        sybDto.setAppid(sybDto.getAppid());
    }
}
